import 'package:reabampos/src/reabam/operation/bean/api_download_db_file_url.dart';
import 'package:reabampos/src/reabam/operation/bean/api_upload_order_task.dart';
import 'package:reabampos/src/reabam/operation/bean/base/rb_request.dart';
import 'package:reabampos/src/reabam/operation/bean/base/rb_response.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_goodtype.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_paytype.dart';
import 'package:reabampos/src/reabam/operation/bean/bean_retry_order.dart';
import 'package:reabampos/src/reabam/operation/bean/check_app_update/Request_check_app_update.dart';
import 'package:reabampos/src/reabam/operation/bean/kuaimai/km_base_request.dart';
import 'package:reabampos/src/reabam/operation/bean/login/request_login.dart';
import 'package:reabampos/src/reabam/operation/bean/login/request_user_info.dart';
import 'package:reabampos/src/reabam/operation/bean/socket/Request_server_ip_list.dart';
import 'package:reabampos/src/reabam/operation/bean/socket/Request_update_serversocket.dart';
import 'package:reabampos/src/reabam/operation/rb_config.dart';
import 'package:reabampos/src/reabam/operation/rb_enum.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_aliyun_log.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';

import 'bean/barcode_rule/Response_barcode_rule.dart';
import 'bean/upload_device_setting_info/request_upload_device_setting_info.dart';

typedef RBApiCallbackSucceed = void Function(
    Map<String, dynamic> responseMap,
    Map<String, dynamic>
        headers_response); //headers_response: Map<String, List<String>>
typedef RBApiCallbackSucceedT<T> = void Function(
    T response,
    Map<String, dynamic> responseMap,
    Map<String, dynamic>
        headers_response); //headers_response: Map<String, List<String>>

abstract class RBBaseApi {
  static Map<String, dynamic>? _getHeaders() {
    Map<String, dynamic> map = {};

    //旧认证
    // String sysNo=XSharePreferencesUtils.getString(RBConfigs.SP_sysNo);
    // if('take_order_hd'==sysNo){
    //   //接单端需要添加Authorization,否则tokenId过期,其他端不能添加Authorization,否则也会tokenId过期
    //   String tokenId = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    //   map['Authorization']='Bearer $tokenId';
    //   return map;
    // }

    //
    String tokenId = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    String group_id = XSharePreferencesUtils.getString(RBConfigs.SP_groupId);
    String company_id =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    String user_id = XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    map['group_id'] = group_id;
    map['company_id'] = company_id;
    map['user_id'] = user_id;
    map['version'] = RBConfigs.versionName;
    map['Authorization'] = 'Bearer $tokenId';

    //自助收银
    if (RBConfigs.versionType == VersionType.officialSelfServiceVersion ||
        RBConfigs.versionType == VersionType.testSelfServiceVersion) {
      map['sourceSysNo'] = 'SelfCheckout';
    }

    return map;
  }

  //处理电子秤结果
  static double? handleWeigherResultToDouble(String brand, String result) {
    try {
      //XLogUtils.printLog('---usb电子秤result=$result');

      if ('顶尖' == brand) {
        //S  0,065KGv

        if (result.contains(',') && result.contains('KG')) {
          int index1 = result.indexOf(',');
          int index2 = result.indexOf('KG');
          String rStatus = result.substring(2, 3);
          String rZhengshu = result.substring(5, index1);
          String rXiaoshu = result.substring(index1 + 1, index2);

          //XLogUtils.printLog('---顶尖,状态:$rStatus, 整数部分:$rZhengshu, 小数部分:$rXiaoshu');

          double zs = XNumberUtils.string2double(rZhengshu) ?? 0;
          double xs = (XNumberUtils.string2double(rXiaoshu) ?? 0) / 1000;

          return zs + xs;
        }
      } else if ('顶尖PS1X' == brand) {
        //S  0.065KGv

        if (result.contains('.') && result.contains('KG')) {
          int index1 = result.indexOf('.');
          int index2 = result.indexOf('KG');
          String rStatus = result.substring(2, 3);
          String rZhengshu = result.substring(5, index1);
          String rXiaoshu = result.substring(index1 + 1, index2);

          //XLogUtils.printLog('---顶尖,状态:$rStatus, 整数部分:$rZhengshu, 小数部分:$rXiaoshu');

          double zs = XNumberUtils.string2double(rZhengshu) ?? 0;
          double xs = (XNumberUtils.string2double(rXiaoshu) ?? 0) / 1000;

          return zs + xs;
        }
      } else if ('大华' == brand) {
        //0510
        if (result.length >= 4) {
          int length = result.length;
          String rZhengshu = result.substring(0, length - 3);
          String rXiaoshu = result.substring(length - 3, length);

          //XLogUtils.printLog('---大华,整数部分:$rZhengshu, 小数部分:$rXiaoshu');

          double zs = XNumberUtils.string2double(rZhengshu) ?? 0;
          double xs = (XNumberUtils.string2double(rXiaoshu) ?? 0) / 1000;

          return zs + xs;
        }
      }
    } catch (e) {
      //
    }

    return null;
  }

  static void requestApi_async({
    required String url,
    String? requestJson,
    Map<String, dynamic>? requestMap,
    bool disableRetry = true, //默认关闭自动重试
    Duration? receiveTimeout,
    Map<String, dynamic>? headers,
    bool isThirdPartyApi = false,
    required RBApiCallbackSucceed succeed,
    required XHttpCallbackFailed failed,
  }) {
    if (requestMap != null) {
      requestMap['tokenId'] =
          XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    }

    XHttpUtils.request_async(
        url: url,
        disableRetry: disableRetry,
        receiveTimeout: receiveTimeout,
        headers: headers ?? _getHeaders(),
        dataJson:
            requestMap != null ? XJsonUtils.obj2Json(requestMap) : requestJson,
        succeed: (String result, Map<String, dynamic> headersResponse) {
          if (isThirdPartyApi) {
            succeed(XJsonUtils.json2Map(result), headersResponse);
            return;
          }

          RBBaseResponse response =
              RBBaseResponse.fromJson(XJsonUtils.json2Map(result));
          String? code = response.code;
          String? message = response.msg;
          dynamic ResultInt = response.ResultInt;
          String? ResultString = response.ResultString;

          //XLogUtils.printLog('---response.code=${response.code}');

          if (response.code != null) {
            if (code == "200") {
              succeed(XJsonUtils.json2Map(result), headersResponse);
            } else {
              failed(code ?? '-1', message ?? 'request failed!');

              if (code == "8888" || code == "9999") {
                //自助收银
                if (RBConfigs.versionType ==
                        VersionType.officialSelfServiceVersion ||
                    RBConfigs.versionType ==
                        VersionType.testSelfServiceVersion) {
                  XSharePreferencesUtils.saveString(RBConfigs.SP_tokenId, '');
                  //
                  XNotifyStateChangeUtils.notifyStateChange(
                      action: RBConfigs.Notify_Global_Handler,
                      key: 'backToLoginPage',
                      value: '');
                }
              }
            }
          } else {
            if (ResultInt != null && '$ResultInt' == '0') {
              succeed(XJsonUtils.json2Map(result), headersResponse);
            } else {
              failed('$ResultInt', ResultString ?? 'request failed!');

              if (code == "8888" || code == "9999") {
                //自助收银
                if (RBConfigs.versionType ==
                        VersionType.officialSelfServiceVersion ||
                    RBConfigs.versionType ==
                        VersionType.testSelfServiceVersion) {
                  XSharePreferencesUtils.saveString(RBConfigs.SP_tokenId, '');
                  //
                  XNotifyStateChangeUtils.notifyStateChange(
                      action: RBConfigs.Notify_Global_Handler,
                      key: 'backToLoginPage',
                      value: '');
                }
              }
            }
          }
        },
        failed: failed);
  }

  static Future<Map<String, dynamic>?> requestApi_sync({
    required String url,
    required String requestJson,
  }) async {
    String result = await XHttpUtils.request_sync(
        url: url, headers: _getHeaders(), dataJson: requestJson);

    if (XStringUtils.isEmpty(result)) {
      return null;
    }

    RBBaseResponse response =
        RBBaseResponse.fromJson(XJsonUtils.json2Map(result));
    String? code = response.code;
    String? message = response.msg;
    dynamic ResultInt = response.ResultInt;
    String? ResultString = response.ResultString;

    if (response.code != null) {
      if (code == "200") {
        return XJsonUtils.json2Map(result);
      } else {
        return null;
      }
    } else {
      if (ResultInt != null && '$ResultInt' == '0') {
        return XJsonUtils.json2Map(result);
      } else {
        return null;
      }
    }
  }

  static void login({
    required String mobile,
    required String loginWord,
    required String appVersion,
    String? clientVersion,
    required String jpushRegId,
    required String appType,
    required String loginType,
    String? groupId,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXApiUrl()}/api/reabam-manage-login/user/login";
    //
    LoginRequest request = LoginRequest(
      mobile,
      loginWord,
      appVersion,
      clientVersion,
      jpushRegId,
      appType,
      loginType,
      groupId,
    );
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        headers: {},
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  //用户信息
  static void getUserAuthStatus({
    required RBApiCallbackSucceedT<LoginInfoResponse> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXApiUrl()}/api/reabam-manage/app/Common/GetUserAuthStatus";
    //
    requestApi_async(
        url: url,
        requestMap: {},
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          LoginInfoResponse response = LoginInfoResponse.fromJson(responseMap);
          succeed(response, responseMap, headers_response);
        });
  }

  //////////////////////////////////////////////////

  //快麦处理
  static void requestApi_km({
    required String url,
    required String requestJson,
    required RBApiCallbackSucceed succeed,
    required XHttpCallbackFailed failed,
  }) {
    XHttpUtils.request_async(
        url: url,
        headers: null,
        dataJson: requestJson,
        succeed: (String result, Map<String, dynamic> headersResponse) {
          //BaseKMResponse response=BaseKMResponse.fromJson(XJsonUtils.json2Map(result));
          Map<String, dynamic> response = XJsonUtils.json2Map(result);

          bool? status = response['status'];
          String? message = response['message'];
          if (status == true) {
            succeed(response, headersResponse);
          } else {
            failed('-1', message ?? 'request failed!');
          }
        },
        failed: failed);
  }

  static String getXApiUrl() {
    return RBConfigs.apiUrl;
  }

  static String getXServerUrl() {
    return XSharePreferencesUtils.getString(RBConfigs.SP_serverAddress);
  }

  static String getXServerUrl2() {
    return XSharePreferencesUtils.getString(RBConfigs.SP_zuulServerAddress);
  }

  ////////////////////////////////////////////////////////////

  //检查版本升级
  static void checkAppVersionUpdate({
    required String appCode,
    required RBApiCallbackSucceedT<ResponseCheckAppUpdate> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/om/app/checkAppVersion";
    //
    RequestCheckAppUpdate request =
        RequestCheckAppUpdate(appCode, '${RBConfigs.version}');
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          ResponseCheckAppUpdate response =
              ResponseCheckAppUpdate.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  static void getShopCartDetail({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-shoppingcart-front/app/shopCart/pos/getShopCartDetail";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    requestMap['userId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_userId);

    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //门店列表
  static void getStaffStoreList({
    required String? sword,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/reabam-manage/staff/comp/login/list";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['sword'] = sword;
    requestMap['userId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    requestMap['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);

    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //切换品牌/门店
  static void changePinPaiShangOrCompany({
    required String? groupId,
    required String? companyId,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXApiUrl()}/api/reabam-manage-login/user/change/login";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['groupId'] = groupId;
    requestMap['companyId'] = companyId;
    requestMap['userId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_userId);

    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  //会员搜索
  static void searchMemberList({
    required String? searchWord,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/reabam-retail-fast/app/Business/Member/Search";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['orderField'] = 'date';
    requestMap['orderSort'] = 'desc';
    requestMap['filterType'] = 2;
    requestMap['entrance'] = 1;
    requestMap['pageIndex'] = 1;
    requestMap['pageSize'] = 20;
    requestMap['searchWord'] = searchWord;

    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  static void getStaffList({
    required int pageIndex,
    required String? sword,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-order-fast/orderfast/app/Business/Staff/List";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['sword'] = sword;
    requestMap['pageIndex'] = pageIndex;
    requestMap['pageSize'] = 20;

    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  static void updateStaff({
    required String? staffId,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-shoppingcart-front/app/shopping/cart/updateItemStaff";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    requestMap['userId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    requestMap['staffId'] = staffId;

    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //商品分类
  static void goodTypeList({
    required String optType,
    required String filterType,
    required RBApiCallbackSucceedT<GoodTypeResponse> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/product-front/app/Business/Order/ProductTypes";

    //
    GoodTypeRequest request =
        GoodTypeRequest(optType: optType, filterType: filterType);
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          GoodTypeResponse response = GoodTypeResponse.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  //支付方式
  static void payList({
    String? equipmentIdentity,
    required RBApiCallbackSucceedT<PayTypeResponse> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-pay-front/app/Common/AppCode/PayType";
    //
    PayTypeRequest request =
        PayTypeRequest(equipmentIdentity: equipmentIdentity);
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          PayTypeResponse response = PayTypeResponse.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  //刷新订单是否已追平接口
  static Future<Response_retry_pos_order?> retryPosOrder({
    required List<String> fastOrderNos,
    required String groupId,
  }) async {
    //
    String url =
        "${getXServerUrl2()}/retail-order-front/fast/order/task/push/retry/batch/pos";
    //
    Request_retry_pos_order request = Request_retry_pos_order();
    request.fastOrderNos = fastOrderNos;
    request.groupId = groupId;
    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    if (responseMap != null) {
      Response_retry_pos_order response =
          Response_retry_pos_order.fromJson(responseMap);
      return response;
    }

    return null;
  }

  //检测订单是否已追平
  static Future<Response_check_order?> checkOrderBusinessStatus({
    required List<String> fastOrderNos,
  }) async {
    //
    String url =
        "${getXServerUrl2()}/retail-order-front/fast/order/task/push/checker";
    //
    Request_retry_pos_order request = Request_retry_pos_order();
    request.fastOrderNos = fastOrderNos;
    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    if (responseMap != null) {
      Response_check_order response =
          Response_check_order.fromJson(responseMap);
      return response;
    }

    return null;
  }

  //上传任务
  static Future<Response_upload_order?> uploadOrderTask(
      {String? taskId,
      String? typeCode,
      String? fastOrderNo,
      String? pushJson,
      String? pushVersion,
      String? pushClient}) async {
    //
    String url = "${getXServerUrl2()}/retail-order-front/fast/order/task/push";
    //
    Request_upload_order request = Request_upload_order(
        taskId: taskId,
        typeCode: typeCode,
        fastOrderNo: fastOrderNo,
        pushJson: pushJson,
        pushVersion: pushVersion,
        pushClient: pushClient);
    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    if (responseMap != null) {
      Response_upload_order response =
          Response_upload_order.fromJson(responseMap);
      return response;
    }

    return null;
  }

  //上传任务2.0
  static Future<Response_upload_order?> uploadOrderTask2(
      {required Map<String, dynamic> request}) async {
    //
    String url =
        "${getXServerUrl2()}/retail-order-front/fast/order/task/push/comb";
    //
    String tokenId = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);
    request['tokenId'] = tokenId;

    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    if (responseMap != null) {
      Response_upload_order response =
          Response_upload_order.fromJson(responseMap);
      return response;
    }

    return null;
  }

  static void downloadDBFileWaitH5CallbackFileUrl({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/product-task/offlinePos/downloadOfflineProducts";
    //
    RequestDownloadDbFileUrl request = RequestDownloadDbFileUrl();
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  static void h5RequestApiCommon({
    required String url,
    required String json,
    required String key,
    required RBApiCallbackSucceedT<String> succeed,
  }) {
    requestApi_async(
        url: url,
        requestJson: json,
        failed: (String code, String msg) {
          //不用失败情况,也不用通知h5
        },
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed('', responseMap, headersResponse);
        });
  }

  //上传更新serverSocket ip
  static void updateServerSocketInfo({
    required List<BeanSocketPrintSetDTOS> printSetDTOS,
    required RBApiCallbackSucceedT<RBBaseResponse> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/retail-order-front/printSet/save";
    //
    RequestUpdateServerSocket request = RequestUpdateServerSocket(printSetDTOS);
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          RBBaseResponse response = RBBaseResponse.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  //获得serverSocket ip
  static void getServerIPList({
    required RBApiCallbackSucceedT<ResponseGetServerIPList> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/retail-order-front/printSet/info";
    //
    RequestGetServerIPList request = RequestGetServerIPList(
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId));
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          ResponseGetServerIPList response =
              ResponseGetServerIPList.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

/*
     增量更新商品数据
     */
  static Future<Response_updateGoodItemsDB?> updateGoodItemsDB({
    required List<String> itemIds,
  }) async {
    //
    String url =
        "${getXServerUrl2()}/product-task/offlinePos/downloadSpecifyOfflineProducts";
    //
    Request_updateGoodItemDB request = Request_updateGoodItemDB();
    request.itemIds = itemIds;
    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    if (responseMap != null) {
      Response_updateGoodItemsDB response =
          Response_updateGoodItemsDB.fromJson(responseMap);
      return response;
    }

    return null;
  }

  //增量促销(单个)
  static void checkPromotion1({
    required String projectId,
    required RBApiCallbackSucceedT<Response_websocket_promotion> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-shoppingcart-task/promotion/data/project/getDownloadUrl";
    //
    Request_websocket_promotion request =
        Request_websocket_promotion(projectId: projectId);
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          Response_websocket_promotion response =
              Response_websocket_promotion.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  //增量促销(门店,品牌)
  static void checkPromotion2({
    required RBApiCallbackSucceedT<Response_websocket_promotion> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-shoppingcart-task/promotion/data/comp/getDownloadUrl";
    //
    RBBaseRequest request = RBBaseRequest();
    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          Response_websocket_promotion response =
              Response_websocket_promotion.fromJson(responseMap);
          succeed(response, responseMap, headersResponse);
        });
  }

  //获得服务端时间
  static void getServerTime({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/retail-order-front/common/system/date";
    //
    requestApi_async(
        url: url,
        requestMap: {},
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //绑定快麦云设备
  static void bindKuaimaiCloudDevice({
    required String? sn,
    String? deviceKey,
    String? bindName,
    String? noteName,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/reabam-hardware-platform/kuaimai/cloud/bindDevice";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['sn'] = sn;
    requestMap['deviceKey'] = deviceKey;
    requestMap['bindName'] = bindName;
    requestMap['noteName'] = noteName;
    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //使用快麦云设备打印 https://showdoc.reabam.com/web/#/52?page_id=8336
  static void useKuaimaiCloudDevicePrint({
    required String? requestId,
    required Map<String, dynamic>? dataSet,
    required String? sn,
    required String? templateId,
    required int? type,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/reabam-hardware-platform/kuaimai/cloud/printData";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['requestId'] = requestId;
    requestMap['dataSet'] = dataSet;
    requestMap['sn'] = sn;
    requestMap['templateId'] = templateId;
    requestMap['type'] = type;
    //
    requestApi_async(
        url: url,
        disableRetry: false,
        receiveTimeout: const Duration(seconds: 5),
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  static Future<ResponseBarcodeRule?> getBarcodeSearchRule() async {
    //
    String url = "${getXServerUrl2()}/config/barcodeSearchRule/getList";
    //
    RBBaseRequest request = RBBaseRequest();
    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    //XLogUtils.printLog('---getBarcodeSearchRule=$responseMap',tag: 'tess');
    if (responseMap != null) {
      ResponseBarcodeRule response = ResponseBarcodeRule.fromJson(responseMap);
      return response;
    }

    return null;
  }

  //又拍云参数
  static void getYoupaiyunConfig({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/core/app/Common/GetUpyunFormParams";
    //
    Map<String, dynamic> requestMap = {};
    requestMap['uploadType'] = 'other';

    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  //保存文件上传记录
  static void saveUpYunInfo({
    required Map<String, dynamic> file_youpaiyun, //又拍云
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    Map<String, dynamic> fileMap = {};
    fileMap['fileName'] = (file_youpaiyun['url'] as String)
        .substring((file_youpaiyun['url'] as String).lastIndexOf('/'));
    fileMap['fileOrgName'] = (file_youpaiyun['url'] as String)
        .substring((file_youpaiyun['url'] as String).lastIndexOf('/') + 1);
    fileMap['fileSize'] = file_youpaiyun['file_size'];
    fileMap['fileUrl'] = file_youpaiyun['url'];
    fileMap['fileFullUrl'] = file_youpaiyun['fileFullUrl'];

    //
    String url = "${getXServerUrl2()}/core/app/Common/Attachment/Add";

    Map<String, dynamic> requestMap = {};
    List<dynamic> files = [];
    files.add(fileMap);
    requestMap['files'] = files;
    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  //上传设备设置记录
  static void uploadDeviceSettingInfo(
    bool isLogIn, //是否登录时上传,
  ) {
    //https://showdoc.reabam.com/web/#/8?page_id=7394
    String url = "${getXServerUrl2()}/retail-order-front/pos/machine/add";

    //
    RequestUploadDeviceSettingInfo request = RequestUploadDeviceSettingInfo();
    request.logIn = isLogIn;

    request.lastReportingTime =
        XDateUtils.getCurrentTime_String(format: XDateUtils.formatTimeDefault1);
    request.companyId =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    request.companyCode =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyCode);
    request.companyName =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyName);

    //设备号
    String deviceNo = XSharePreferencesUtils.getString(
        "machineCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}");
    request.machineNo = deviceNo.replaceAll('"', deviceNo);

    if (XStringUtils.isEmpty(request.machineNo)) {
      XLogUtils.printLog('---设备号为空,不上传设备设置记录');
      return;
    }

    request.status = "1";

    //切换本地打印
    request.switchLocalPrint = false;
    //本机接单打印
    request.localPrint = XSharePreferencesUtils.getBool(
        'getIsReceiveTakeawayInfo${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',
        defaultValue: false);
    //启用扫码盒扫码
    request.scanCodeBoxPrint = XSharePreferencesUtils.getBool(
        'getIsUseScanBox${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',
        defaultValue: false);
    //极速收银
    request.speedCash = XSharePreferencesUtils.getBool(
        'getIsQuickCash${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',
        defaultValue: true);
    //商品缓存
    request.productCache = XSharePreferencesUtils.getBool(
        'getIsGoodsCache${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}',
        defaultValue: true);

    //取餐码/餐牌号: {"preCode":"S","startNum":"0001","endNum":"9999","nowNum":"0001"}
    //test
    String jsonCmpMealcode = XSharePreferencesUtils.getString(
        "cmp_mealCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}");
    //L.sdk("--json_cmp_mealCode="+json_cmp_mealCode);
    Map<String, dynamic> mapCmpMealcode = XJsonUtils.json2Map(jsonCmpMealcode);
    request.mealTakeCodePrefix = mapCmpMealcode['preCode'];
    request.mealTakeCodeStart = mapCmpMealcode['startNum'];
    request.mealTakeCodeEnd = mapCmpMealcode['endNum'];
    request.mealTakeCodeNum = mapCmpMealcode['nowNum'];

    //打印机
    List<PosMachinePrintersBean> posMachinePrinters = [];

    XBaseDevice? socketTv;
    Set<XBaseDevice> connectedDeviceList = XSocketUtils.socketDeviceList;
    XLogUtils.printLog('---socket size=${connectedDeviceList.length}');
    for (XBaseDevice item in connectedDeviceList) {
      if (RBConfigs.SocketTV == item.customType) {
        socketTv = item;
      } else if (RBConfigs.IPPrinter == item.customType) {
        PosMachinePrintersBean iitem = PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType = "0";
        iitem.printerName = item.deviceName;
        iitem.ip = item.ip;
        iitem.lineNo = item.serialNumber;

        List<XBaseDeviceScene>? scenes = item.scenes;
        StringBuffer sb = StringBuffer();
        if (scenes != null) {
          for (int j = 0; j < scenes.length; j++) {
            if (j == scenes.length - 1) {
              sb.write(scenes[j].name);
            } else {
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr = sb.toString();
        if (XStringUtils.isEmpty(tagStr)) {
          tagStr = "无";
        }
        iitem.scene = tagStr;
        //
        posMachinePrinters.add(iitem);
      }
    }

    //叫号屏ip地址
    if (socketTv != null) {
      request.queueNumberBoardIp = socketTv.ip;
      request.queueNumberBoardStatus = socketTv.isConnected;
    }

    //usb打印
    Set<XBaseDevice> usbDeviceList = XUsbUtils.usbDeviceList;
    for (XBaseDevice item in usbDeviceList) {
      if (RBConfigs.USBPrinter == item.customType) {
        PosMachinePrintersBean iitem = PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType = "1";
        iitem.printerName = item.deviceName;
        iitem.printerId = item.deviceUUID;
        iitem.lineNo = item.serialNumber;

        List<XBaseDeviceScene>? scenes = item.scenes;
        StringBuffer sb = StringBuffer();
        if (scenes != null) {
          for (int j = 0; j < scenes.length; j++) {
            if (j == scenes.length - 1) {
              sb.write(scenes[j].name);
            } else {
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr = sb.toString();
        if (XStringUtils.isEmpty(tagStr)) {
          tagStr = "无";
        }
        iitem.scene = tagStr;
        //
        posMachinePrinters.add(iitem);
      }
    }

    //蓝牙
    XBaseDevice? weigherBluetooth;
    Set<XBaseDevice> bluetoothBLEDeviceList =
        XBluetoothBLEUtils.bluetoothBLEDeviceList;
    for (XBaseDevice item in bluetoothBLEDeviceList) {
      if (RBConfigs.BluetoothPrinter == item.customType) {
        PosMachinePrintersBean iitem = PosMachinePrintersBean();
        //打印机类型：0-网络、 1-USB、 2-蓝牙
        iitem.printerType = "2";
        iitem.printerName = item.deviceName;
        iitem.printerId = item.bluetoothAddress;
        iitem.lineNo = item.serialNumber;

        List<XBaseDeviceScene>? scenes = item.scenes;
        StringBuffer sb = StringBuffer();
        if (scenes != null) {
          for (int j = 0; j < scenes.length; j++) {
            if (j == scenes.length - 1) {
              sb.write(scenes[j].name);
            } else {
              sb.write("${scenes[j].name},");
            }
          }
        }
        String tagStr = sb.toString();
        if (XStringUtils.isEmpty(tagStr)) {
          tagStr = "无";
        }
        iitem.scene = tagStr;
        //
        posMachinePrinters.add(iitem);
      } else if (RBConfigs.BluetoothWeigher == item.customType) {
        weigherBluetooth = item;
      }
    }

    //蓝牙电子秤名称
    if (weigherBluetooth != null) {
      request.bluetoothScaleName = weigherBluetooth.deviceName;
    }

    //远程打印机(快麦云打印)
    Set<XBaseDevice> kuaimaiCloudDeviceList =
        XRemoteDeviceUtils.remoteDeviceList;
    for (XBaseDevice item in kuaimaiCloudDeviceList) {
      PosMachinePrintersBean iitem = PosMachinePrintersBean();
      //打印机类型：0-网络、 1-USB、 2-蓝牙  3-云打印
      iitem.printerType = "3";
      iitem.printerName = item.deviceName;
      iitem.printerId = item.deviceUUID;
      iitem.lineNo = item.serialNumber;

      List<XBaseDeviceScene>? scenes = item.scenes;
      StringBuffer sb = StringBuffer();
      if (scenes != null) {
        for (int j = 0; j < scenes.length; j++) {
          if (j == scenes.length - 1) {
            sb.write(scenes[j].name);
          } else {
            sb.write("${scenes[j].name},");
          }
        }
      }
      String tagStr = sb.toString();
      if (XStringUtils.isEmpty(tagStr)) {
        tagStr = "无";
      }
      iitem.scene = tagStr;
      //
      posMachinePrinters.add(iitem);
    }

    //打印机
    request.posMachinePrinters = posMachinePrinters;

    //
    requestApi_async(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: (String code, String msg) {
          //
        },
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          //
        });
  }

  //快麦打印//////////////////////////////////////////////////////////////////////////

  //测试域名
  //String _kmUrl="http://label-component-test.kuaimai.com";
  //正式域名
  static const String _kmUrl = "http://label-component.kuaimai.com";

  static const String _kmAppId = "1625638525787";
  static const String _kmAppSecret = "dabef9624c4d4a318cd9843584c2ef1c";

  //快麦api签名
  static void _setKuaimaiSign(BaseKMRequest request) {
    String timestamp =
        XDateUtils.getCurrentTime_String(format: XDateUtils.formatTimeDefault2);
    String randomNum = '${XNumberUtils.randomInt(12345678) + 200000000}';
    String x = '$_kmAppSecret$_kmAppId$timestamp$randomNum$_kmAppSecret';
    String sign = XJiamiUtils.strToMd5(x).toLowerCase();
    request.appId = _kmAppId;
    request.timestamp = timestamp;
    request.randomNum = randomNum;
    request.sign = sign;
  }

  //小票打印命令获取
  static void kmXiaopiaoPrint(
      {required String templateId,
      required String renderData,
      required String requestId,
      required RBApiCallbackSucceedT succeed,
      required XHttpCallbackFailed failed}) {
    //
    String url = "$_kmUrl/api/label/component/getEscInstruct";
    //
    Request_km_xiaopiao request = Request_km_xiaopiao(
        templateId: templateId, renderData: renderData, requestId: requestId);
    _setKuaimaiSign(request);

    //
    requestApi_km(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          //Response_km_xiaopiao response=Response_km_xiaopiao.fromJson(responseMap);
          succeed(null, responseMap, headersResponse);
        });
  }

  //tspl标签打印
  static void kmTSPLPrint(
      {required String templateId,
      required String renderData,
      required String requestId,
      required RBApiCallbackSucceedT succeed,
      required XHttpCallbackFailed failed}) {
    //
    String url = "$_kmUrl/api/label/component/getTsplInstruct";
    //
    Request_km_biaoqian request = Request_km_biaoqian(
      templateId: templateId,
      renderData: renderData,
      requestId: requestId,
    );
    _setKuaimaiSign(request);

    //
    requestApi_km(
        url: url,
        requestJson: XJsonUtils.obj2Json(request),
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          //Response_km_xiaopiao response=Response_km_xiaopiao.fromJson(responseMap);
          succeed(null, responseMap, headersResponse);
        });
  }

// public void kmXiaopiaoPrintPreview(Context context,
//     String templateId,
//     String renderData,
//     String requestId,
//     final XResponseListener2<Response_km_xiaopiaoPreview> listener) {
//
//   String url = kmUrl + "/api/label/component/getEscInstructImage";
//
//   Request_km_xiaopiao request = new Request_km_xiaopiao();
//   setKuaimaiSign(request);
//
//   request.templateId = templateId;
//   request.renderData = renderData;
//   request.requestId = requestId;
//
//   requestJsonByOkHttpPost_km(
//       context,
//       api.getAndroid_UUID(),
//       url,
//       request,
//       new HandlerResponse_CallBack_km<Response_km_xiaopiaoPreview>(context, Response_km_xiaopiaoPreview.class) {
//   @Override
//   public void failed(String s, String s1) {
//   listener.failed(s, s1);
//   }
//
//   @Override
//   public void succeed(Response_km_xiaopiaoPreview response, Map<String, String> headerMap) {
//   listener.succeed(response, headerMap);
//   }
//   });
// }

  //单张识别 https://showdoc.reabam.com/web/#/54?page_id=8522
  static void aiRecognitionImage({
    required String file, //base64
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/reabam-ai/ai/recognition/single/img";

    Map<String, dynamic> requestMap = {};
    requestMap['file'] = file;
    //
    requestApi_async(
        url: url,
        requestMap: requestMap,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headers_response) {
          succeed(null, responseMap, headers_response);
        });
  }

  ///////////////////////////////////////////////////////////////////////////////

  //初始化阿里云日志
  static void initAliyunLog(String appName) {
    String endpoint;
    String project;
    String logstore;
    String accesskeyid;
    String accesskeysecret;

    if (RBConfigs.versionType == VersionType.testVersion ||
        RBConfigs.versionType == VersionType.developerVersion) {
      //测试版
      endpoint = 'https://cn-shenzhen.log.aliyuncs.com';
      project = 'reabam-app-log';
      logstore = 'pos_app_android_test';
      accesskeyid = 'LTAI5t6gtXxdKepYHRymyFTX';
      accesskeysecret = 'wwrc7roPwIlAzYGMLSNfhhDn7nkyWL';
    } else {
      //正式版
      endpoint = 'https://cn-shenzhen.log.aliyuncs.com';
      project = 'reabam-app-log';
      logstore = 'pos_app_android_prod';
      accesskeyid = 'LTAI5t6gtXxdKepYHRymyFTX';
      accesskeysecret = 'wwrc7roPwIlAzYGMLSNfhhDn7nkyWL';
    }

    //
    String deviceNo = XSharePreferencesUtils.getString(
        'machineCode${XSharePreferencesUtils.getString(RBConfigs.SP_companyId)}');

    Map<String, dynamic> customTags = {};
    customTags['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    customTags['companyName'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyName);
    customTags['userCode'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_userCode);
    customTags['userName'] =
        '${XSharePreferencesUtils.getString(RBConfigs.SP_userName)}, userId=${XSharePreferencesUtils.getString(RBConfigs.SP_userId)}, tokenId=${XSharePreferencesUtils.getString(RBConfigs.SP_tokenId)}';
    customTags['设备号'] = deviceNo;
    customTags['设备信息'] = XJsonUtils.obj2Json(XTempData.deviceInfo);

    //睿本云HD
    XAliyunLogUtils.init(
      appName: '${appName}_${RBConfigs.versionName}_${XFlutterUtils.version}',
      endpoint: endpoint,
      project: project,
      logstore: logstore,
      accessKeyID: accesskeyid,
      accessKeySecret: accesskeysecret,
      customTags: customTags,
    );
  }

  //重新获取支付方式和商品分类
  static void initGetPayTypeAndGoodType() {
    String companyId = XSharePreferencesUtils.getString(RBConfigs.SP_companyId);

    XLogUtils.printLog('---1.重新获取商品分类');
    RBBaseApi.goodTypeList(
        optType: '2',
        filterType: 'Order',
        failed: (String code, String msg) {
          XLogUtils.printLog('---重新获取商品分类失败: code:$code,msg=$msg');
        },
        succeed: (GoodTypeResponse response, Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) async {
          //保存商品分类
          dynamic DataLine = responseMap['DataLine'];
          String pTypeJson = XJsonUtils.obj2Json(DataLine);
          XSharePreferencesUtils.saveString(
              '${RBConfigs.SP_Pos_OfflineDB_goodsType}$companyId', pTypeJson);
          XLogUtils.printLog('---重新获取商品分类pTypeJson=$pTypeJson');
        });

    //下载支付方式
    XLogUtils.printLog('---2.重新获取下载商品分类');
    RBBaseApi.payList(
      equipmentIdentity: RBConfigs.isShangMiDevice ? "sumipay" : null,
      failed: (String code, String msg) {
        XLogUtils.printLog('---重新获取下载商品分类失败: code:$code,msg=$msg');
      },
      succeed: (PayTypeResponse response, Map<String, dynamic> responseMap1,
          Map<String, dynamic> headersResponse) {
        //
        dynamic DataLine1 = responseMap1['DataLine'];
        //保存支付方式
        XSharePreferencesUtils.saveString(
            RBConfigs.SP_Pos_OfflineDB_payType + companyId,
            XJsonUtils.obj2Json(DataLine1));
      },
    );
  }

  //自助收银///////////////////////////////////////////////////////////////////////////

  static void getSelfServiceSettingInfo({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-order-fast/retail/self/checkout/get/info";
    //
    Map<String, dynamic> request = {};
    request['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    //
    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  static void getPrintSet({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-order-fast/app/Business/config/printset/get";
    //
    Map<String, dynamic> request = {};
    request['typeCode'] = 'SalesOrder';
    //
    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //自助收银上传订单2.0
  static void uploadOrderTask_SelfService({
    required String combTaskId,
    required String fastOrderNo,
    required List<dynamic> fastOrderTasks,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-order-front/fast/order/task/push/comb";
    //
    Map<String, dynamic> request = {};
    request['combTaskId'] = combTaskId;
    request['fastOrderNo'] = fastOrderNo;
    request['fastOrderTasks'] = fastOrderTasks;

    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //反扫支付
  static void pay_ss({
    required String payType,
    required String payTypeName,
    required String? orderId,
    required String? memberId,
    required List<dynamic>? items,
    required double? payAmount,
    required String? scanCode,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url = "${getXServerUrl2()}/reabam-pay-front/app/pay/$payType";
    //
    Map<String, dynamic> request = {};
    request['orderType'] = 'speedOfflineOrder';
    request['payType'] = payType;
    request['paycode'] = payType;
    request['payTypeName'] = payTypeName;
    request['orderId'] = orderId;
    request['orderNo'] = orderId;
    request['sourceOrderNo'] = orderId;
    request['requestId'] = orderId;
    request['memberId'] = memberId;
    request['remark'] = '';
    request['items'] = items;
    request['payAmount'] = payAmount;
    request['authCode'] = scanCode;
    request['attach'] = scanCode;
    request['userId'] = XSharePreferencesUtils.getString(RBConfigs.SP_userId);
    request['companyId'] =
        XSharePreferencesUtils.getString(RBConfigs.SP_companyId);
    //request['companyAddress']=;

    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  static void pay_check({
    required String? requestId,
    required String? gatheringId,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/reabam-pay-front/app/pay/gathering/refresh";
    //
    Map<String, dynamic> request = {};
    request['gatheringId'] = gatheringId;
    request['requestId'] = requestId;

    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //获取机器码
  static void getMachineCode({
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    //
    String url =
        "${getXServerUrl2()}/retail-order-front/common/machine/code/get";
    //
    Map<String, dynamic> request = {};

    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //支付刷新接口
  static Future<Map<String, dynamic>?> refreshYichangOrderPay({
    dynamic gatheringId, //收银id
    dynamic requestId, //收银支付请求id
    dynamic groupId, //品牌id
  }) async {
    //
    String url =
        "${getXServerUrl2()}/reabam-pay-front/app/pay/gathering/refresh";
    //
    Map<String, dynamic> request = {};
    request['gatheringId'] = gatheringId;
    request['requestId'] = requestId;
    request['groupId'] = groupId;
    request['tokenId'] = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);

    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    return responseMap;
  }

  //取消下单前核销优惠券、团购券、第三方券
  static Future<Map<String, dynamic>?> cancelOrderPrePay({
    required Map request, //收银id
  }) async {
    //
    String url =
        "${getXServerUrl2()}/retail-order-fast/pos/speed/order/add/pre2/cancel";
    //
    request['tokenId'] = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);

    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    return responseMap;
  }

  //支付原路退回
  static Future<Map<String, dynamic>?> refundPay({
    required dynamic requestId,
    required dynamic paycode,
    required dynamic orderId,
    required dynamic payChannel,
  }) async {
    //
    String url =
        "${getXServerUrl2()}/retail-pay-front/pay/refund/th/originalRefund";
    //
    Map<String, dynamic> request = {};
    request['requestId'] = requestId;
    request['payType'] = paycode;
    request['orderId'] = orderId;
    request['payChannel'] = payChannel;
    request['tokenId'] = XSharePreferencesUtils.getString(RBConfigs.SP_tokenId);

    //
    Map<String, dynamic>? responseMap = await requestApi_sync(
        url: url, requestJson: XJsonUtils.obj2Json(request));

    return responseMap;
  }

  //获得通用配置信息
  static void get_common_config({
    dynamic payType,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    String url = "${getXServerUrl2()}/config/retail/config/get";
    //
    Map<String, dynamic> request = {};
    request['payType'] = payType;

    requestApi_async(
        url: url,
        requestMap: request,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //KPay支付////////////////////////////////////////////////
  //https://docs-posserver.kpay-group.com/#/zh-hk/apiv2/index
  //账号kpay    密码 oL9r8mruJIU

  //kpay请求头
  static Map<String, dynamic> _getKpayHeader({
    bool isNeedSign = true,
    String? type,
    String? requestBodyJsonStr,
  }) {
    //
    Map<String, dynamic> headers = {};
    headers['Content-Type'] = 'application/json';
    int timestamp = XDateUtils.getCurrentTime_ms();
    headers['timestamp'] = '$timestamp';

    //需求签名
    if (isNeedSign) {
      String KPay_appId =
          XSharePreferencesUtils.getString(RBConfigs.SP_KPay_appId);
      headers['appId'] = KPay_appId;
      String nonceStr = XFlutterUtils.getUUID(isRandom: true);
      headers['nonceStr'] = nonceStr;

      String KPay_appPrivateKey =
          XSharePreferencesUtils.getString(RBConfigs.SP_KPay_appPrivateKey);

      String url = "";
      if (type == 'kPaySalse') {
        //kPay消費交易
        url = "/v2/pos/sales";
      } else if (type == 'kPaySalseCance') {
        //kPay撤銷交易
        url = "/v2/pos/sales/cancel";
      } else if (type == 'kPaySalseRefund') {
        //kPay交易退款
        url = "/v2/pos/sales/refund";
      } else if (type == 'kPaySalseClose') {
        //kPay關閉交易
        url = "/v2/pos/sales/close";
      } else if (type == 'kPayQuery') {
        //kPay查詢交易
        url = "/v2/pos/query";
      } else {
        url = "";
      }

      //
      String signData =
          'POST\n$url\n$timestamp\n$nonceStr\n$requestBodyJsonStr\n';

      //使⽤工作密鑰對待簽名串進⾏SHA256 with RSA 簽名
      String signatureSHA256 =
          XJiamiUtils.strToSHA(signData, privateKey: KPay_appPrivateKey);
      XLogUtils.printLog('---signatureSHA256=$signatureSHA256');

      //並對簽名結果進⾏Base64編碼得到簽名值
      String signatureBase64 = XJiamiUtils.strToBase64(signatureSHA256);
      XLogUtils.printLog('---signatureBase64=$signatureBase64');

      headers['signature'] = signatureBase64;
    }

    return headers;
  }

  //http://192.168.8.156:18080
  //kpay签到ok
  static void Kpay_sign({
    required String? appId,
    required String? appSecret,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    String KPayDeviceIP =
        XSharePreferencesUtils.getString(RBConfigs.SP_KPay_DeviceIP);
    if (XStringUtils.isEmpty(KPayDeviceIP) ||
        XStringUtils.isEmpty(appId) ||
        XStringUtils.isEmpty(appSecret)) {
      return;
    }
    //
    String url = "http://$KPayDeviceIP:18080/v2/pos/sign";
    //
    Map<String, dynamic> request = {};
    request['appId'] = appId;
    request['appSecret'] = appSecret;

    requestApi_async(
        url: url,
        requestMap: request,
        headers: _getKpayHeader(isNeedSign: false),
        isThirdPartyApi: true,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }

  //kpay通用api
  static void kPayAPI({
    required String type,
    required dynamic requestBody,
    required RBApiCallbackSucceedT<dynamic> succeed,
    required XHttpCallbackFailed failed,
  }) {
    String KPayDeviceIP =
        XSharePreferencesUtils.getString(RBConfigs.SP_KPay_DeviceIP);

    if (XStringUtils.isEmpty(KPayDeviceIP)) {
      return;
    }
    //
    String url = "";
    if (type == 'kPaySalse') {
      //kPay消費交易
      url = "http://$KPayDeviceIP:18080/v2/pos/sales";
    } else if (type == 'kPaySalseCance') {
      //kPay撤銷交易
      url = "http://$KPayDeviceIP:18080/v2/pos/sales/cancel";
    } else if (type == 'kPaySalseRefund') {
      //kPay交易退款
      url = "http://$KPayDeviceIP:18080/v2/pos/sales/refund";
    } else if (type == 'kPaySalseClose') {
      //kPay關閉交易
      url = "http://$KPayDeviceIP:18080/v2/pos/sales/close";
    } else if (type == 'kPayQuery') {
      //kPay查詢交易
      url = "http://$KPayDeviceIP:18080/v2/pos/query";
    } else {
      url = "";
    }

    if (XStringUtils.isEmpty(url)) {
      return;
    }

    String? requestBodyStr;
    if (requestBody is String) {
      requestBodyStr = requestBody;
    } else if (requestBody is Map) {
      requestBodyStr = XJsonUtils.obj2Json(requestBody);
    }

    requestApi_async(
        url: url,
        requestJson: requestBodyStr,
        headers: _getKpayHeader(
          type: type,
          requestBodyJsonStr: requestBodyStr,
        ),
        isThirdPartyApi: true,
        failed: failed,
        succeed: (Map<String, dynamic> responseMap,
            Map<String, dynamic> headersResponse) {
          succeed(null, responseMap, headersResponse);
        });
  }
}
